package infoRetriever;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.Map.Entry;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class OnlineInfoRetriever {
	
	private TrackListHandler trackListHandler;
	private ArtistInfoHandler artistInfoHandler;
	private AlbumInfoHandler albumInfoHandler;
	private List<Album> albums;
	
	private String debug = "";
	private String artist;
	
	private boolean error;
	private boolean artistRetrieved;
	
	private static String LAST_FM_API = "c71d2d4615467f0cf6d624ee5c5660c0";
	
	public OnlineInfoRetriever(){
		artistRetrieved = false;
		error = false;
		
		albums = new Vector<Album>();
		trackListHandler = new TrackListHandler();
		artistInfoHandler = new ArtistInfoHandler();
		albumInfoHandler = new AlbumInfoHandler();
	}
	
	public void retrieveArtist(String artist){
		this.artist = artist;
		
		GetArtistInfo(artist);
	
		if(error) {
			artistRetrieved = false;
			error = false;
			System.out.println("error");
		} else
			artistRetrieved = true;
	}
	public Album addAlbum(String albumName){
		GetAlbumInfo(albumName, artist);
		if(!error)
		{
			Album album = new Album( 
					albumInfoHandler.getName() , albumInfoHandler.getImage(),
					albumInfoHandler.getAlbumInfo(), albumInfoHandler.getMbId());
			ProcessTrackList(albumInfoHandler.getMbId());
			if(!error)
				album.setOrderedTracks(trackListHandler.getTracks());
			error = false;
			return album;
		}
		error = false;
		return null;
	}
	
	public String getArtist(){
		if(artistRetrieved)
			return artist;
		else
			return "no artist loaded";
	}
	
	public String getArtistInfo(){
		if(artistRetrieved)
			return artistInfoHandler.getArtistInfo();
		else
			return "no artist loaded";
	}

	public String getArtistImage(){
		if(artistRetrieved)
			return artistInfoHandler.getImage();
		else
			return "no artist loaded";
	}
	
	public List<Album> getAlbums() {
		return albums;
	}

	private String createFullUrl(String url, Map<String,String> params){
    	String result = url;
    	result = result.concat("?");
    	Iterator<Entry<String, String>> it = params.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String,String> pairs = (Map.Entry<String,String>)it.next();
            result = result.concat(pairs.getKey() + "=" + pairs.getValue());
            if(it.hasNext())
            	result = result.concat("&");
        }
        result = result.replace(" ", "%20");
    	return result;
    }

	private void retrieveData(String baseUrl, Map<String,String> params, DefaultHandler handler){
		try {			
            URL url = new URL(createFullUrl(baseUrl, params));
            URLConnection conn = url.openConnection ();
			
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();
			XMLReader xr = sp.getXMLReader();
			xr.setContentHandler(handler);	
			xr.setErrorHandler(handler);
			System.out.println();
			xr.parse(new InputSource(conn.getInputStream()));

			/*InputStreamReader isr = new InputStreamReader(conn.getInputStream());
			BufferedReader input = new BufferedReader(isr);
	        
	        String line; 
	        while ((line = input.readLine()) != null) {
	            System.out.println(line);   // process each line
	        }*/

		
		} catch (IOException e) {
			e.printStackTrace();
			debug = debug + "io ex" + e.getMessage();
			error = true;
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			debug = debug + "parser ex" + e.getMessage();
			error = true;
		} catch (SAXException e) {
			e.printStackTrace();
			debug = debug + "sax ex" + e.getMessage();
			error = true;
		}
	}
	
    private void ProcessTrackList(String albumId) {
    	String url = "http://musicbrainz.org/ws/1/track/";

		Map<String,String> params = new HashMap<String,String>();
        params.put("type", "xml");
        params.put("releaseid", albumId);
        
        retrieveData(url, params, trackListHandler);
    }
    private void GetArtistInfo(String artist) {
    	String url = "http://ws.audioscrobbler.com/2.0/";

		Map<String,String> params = new HashMap<String,String>();
        params.put("method", "artist.getinfo");
        params.put("artist", artist);
        params.put("api_key", LAST_FM_API);
        
        retrieveData(url, params, artistInfoHandler);
    }
    
    private void GetAlbumInfo(String albumName, String artistName) {
    	String url = "http://ws.audioscrobbler.com/2.0/";
		Map<String,String> params = new HashMap<String,String>();
        params.put("method", "album.getinfo");
        params.put("album", albumName);
        params.put("artist", artistName);
        params.put("api_key", LAST_FM_API);
        
        retrieveData(url, params, albumInfoHandler);
    }
    
    public String InfoToString() {
    	return artistInfoHandler.toString() + "\n"
    	 	+ "debug: " + debug;
    }
}
